/* Copyright (c) 2006-2011 by OpenLayers Contributors (see authors.txt for 
 * full list of contributors). Published under the Clear BSD license.  
 * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
 * full text of the license. */

/**
 * @requires OpenLayers/Layer/XYZ.js
 * @requires OpenLayers/Layer/SphericalMercator.js
 */

/** 
 * Class: OpenLayers.Layer.Bing
 * Bing layer using direct tile access as provided by Bing Maps REST Services.
 * See http://msdn.microsoft.com/en-us/library/ff701713.aspx for more
 * information. Note: Terms of Service compliant use requires the map to be
 * configured with an <OpenLayers.Control.Attribution> control and the
 * attribution placed on or near the map.
 * 
 * Inherits from:
 *  - <OpenLayers.Layer.XYZ>
 */
OpenLayers.Layer.GoogleMap = OpenLayers.Class(OpenLayers.Layer.XYZ, {

    /**
     * Property: serverResolutions
     * {Array} the resolutions provided by the Bing servers.
     */
    serverResolutions: [
        /*156543.03390625, 78271.516953125, 39135.7584765625,
        19567.87923828125, 9783.939619140625, 4891.9698095703125,
        2445.9849047851562, 1222.9924523925781, 611.4962261962891,
        305.74811309814453, 152.87405654907226, 76.43702827453613,
        38.218514137268066, 19.109257068634033, 9.554628534317017,
        4.777314267158508, 2.388657133579254, 1.194328566789627,
        0.5971642833948135, 0.29858214169740677, 0.14929107084870338,
        0.07464553542435169*/
		156543.033928,
		78271.516964,
		39135.758482,
		19567.879241,
		9783.9396205,
		4891.96981025,
		2445.984905125,
		1222.9924525625,
		611.49622628125,
		305.748113140625,
    	152.8740565703125,
		76.43702828515625,
		38.21851414257812,
		19.10925707128906,
		9.55462853564453,
		4.777314267822265,
		2.3886571339111327,
		1.1943285669555663,
		0.5971642834777832,
		0.2985821417388916
    ],
    

    /**
     * Property: metadata
     * {Object} Metadata for this layer, as returned by the callback script
     */
    metadata: null,
    
    /**
     * APIProperty: type
     * {String} The layer identifier.  Any non-birdseye imageryType
     *     from http://msdn.microsoft.com/en-us/library/ff701716.aspx can be
     *     used.  Default is "Road".
     */
    type: "Road",
    
    /**
     * APIProperty: metadataParams
     * {Object} Optional url parameters for the Get Imagery Metadata request
     * as described here: http://msdn.microsoft.com/en-us/library/ff701716.aspx
     */
    metadataParams: null,

    /**
     * Constructor: OpenLayers.Layer.Bing
     * Create a new Bing layer.
     *
     * Example:
     * (code)
     * var road = new OpenLayers.Layer.Bing({
     *     name: "My Bing Aerial Layer",
     *     type: "Aerial",
     *     key: "my-api-key-here",
     * });
     * (end)
     *
     * Parameters:
     * config - {Object} Configuration properties for the layer.
     *
     * Required configuration properties:
     * key - {String} Bing Maps API key for your application. Get one at
     *     http://bingmapsportal.com/.
     * type - {String} The layer identifier.  Any non-birdseye imageryType
     *     from http://msdn.microsoft.com/en-us/library/ff701716.aspx can be
     *     used.
     *
     * Any other documented layer properties can be provided in the config object.
     */
    initialize: function(options) {
        options = OpenLayers.Util.applyDefaults({
            sphericalMercator: true
        }, options);
        var name = options.name || "Bing " + (options.type || this.type);
        
        var newArgs = [name, null, options];
        OpenLayers.Layer.XYZ.prototype.initialize.apply(this, newArgs);
        //this.loadMetadata(); 
        
         this.metadata = {
			    "authenticationResultCode": "ValidCredentials",
			    "brandLogoUri": "http:\/\/dev.virtualearth.net\/Branding\/logo_powered_by.png",
			    "copyright": "Copyright  2012 Microsoft and its suppliers. All rights reserved. This API cannot be accessed and the content and any results may not be used, reproduced or transmitted in any manner without express written permission from Microsoft Corporation.",
			    "resourceSets": [{
			        "estimatedTotal": 1,
			        "resources": [{
			            "__type": "ImageryMetadata:http:\/\/schemas.microsoft.com\/search\/local\/ws\/rest\/v1",
			            "imageHeight": 256,
			            "imageUrl": "http:\/\/ecn.{subdomain}.tiles.virtualearth.net\/tiles\/r{quadkey}.jpeg?g=1134&mkt={culture}&shading=hill",
			            "imageUrlSubdomains": ["t0", "t1", "t2", "t3"],
			            "imageWidth": 256,
			            "imageryProviders": [{
			                "attribution": " 2010 NAVTEQ",
			                "coverageAreas": [{
			                    "bbox": [-90, -180, 90, 180],
			                    "zoomMax": 9,
			                    "zoomMin": 1
			                }, {
			                    "bbox": [14, -180, 90, -50],
			                    "zoomMax": 21,
			                    "zoomMin": 10
			                }, {
			                    "bbox": [27, -32, 40, -13],
			                    "zoomMax": 21,
			                    "zoomMin": 10
			                }, {
			                    "bbox": [35, -11, 72, 20],
			                    "zoomMax": 21,
			                    "zoomMin": 10
			                }, {
			                    "bbox": [21, 20, 72, 32],
			                    "zoomMax": 21,
			                    "zoomMin": 10
			                }, {
			                    "bbox": [21.92, 113.14, 22.79, 114.52],
			                    "zoomMax": 21,
			                    "zoomMin": 10
			                }, {
			                    "bbox": [21.73, 119.7, 25.65, 122.39],
			                    "zoomMax": 21,
			                    "zoomMin": 10
			                }, {
			                    "bbox": [0, 98.7, 8, 120.17],
			                    "zoomMax": 21,
			                    "zoomMin": 10
			                }, {
			                    "bbox": [0.86, 103.2, 1.92, 104.45],
			                    "zoomMax": 21,
			                    "zoomMin": 10
			                }]
			            }, {
			                "attribution": " AND",
			                "coverageAreas": [{
			                    "bbox": [-90, -180, 90, 180],
			                    "zoomMax": 21,
			                    "zoomMin": 10
			                }]
			            }, {
			                "attribution": " 2010 MapData Sciences Pty Ltd, PSMA",
			                "coverageAreas": [{
			                    "bbox": [-45, 111, -9, 156],
			                    "zoomMax": 21,
			                    "zoomMin": 5
			                }, {
			                    "bbox": [-49.7, 164.42, -30.82, 180],
			                    "zoomMax": 21,
			                    "zoomMin": 5
			                }]
			            }, {
			                "attribution": " 2010 Zenrin",
			                "coverageAreas": [{
			                    "bbox": [23.5, 122.5, 46.65, 151.66],
			                    "zoomMax": 21,
			                    "zoomMin": 4
			                }]
			            }, {
			                "attribution": " 2010 Intermap",
			                "coverageAreas": [{
			                    "bbox": [49, -11, 60, 2],
			                    "zoomMax": 21,
			                    "zoomMin": 1
			                }]
			            }, {
			                "attribution": " 2012 Microsoft Corporation",
			                "coverageAreas": [{
			                    "bbox": [-90, -180, 90, 180],
			                    "zoomMax": 21,
			                    "zoomMin": 1
			                }]
			            }],
			            "vintageEnd": null,
			            "vintageStart": null,
			            "zoomMax": 21,
			            "zoomMin": 1
			        }]
			    }],
			    "statusCode": 200,
			    "statusDescription": "OK",
			    "traceId": "7a8337156115431c999a60934922b6df|SINM001003|02.00.83.1900|"
			};
    	 this.initLayer();
    	 
    	
    },

    /**
     * Method: loadMetadata
     */
    loadMetadata: function() {
        this._callbackId = "_callback_" + this.id.replace(/\./g, "_");
        // link the processMetadata method to the global scope and bind it
        // to this instance
        window[this._callbackId] = OpenLayers.Function.bind(
            OpenLayers.Layer.Bing.processMetadata, this
        );
        var params = OpenLayers.Util.applyDefaults({
            key: this.key,
            jsonp: this._callbackId,
            include: "ImageryProviders"
        }, this.metadataParams);
        var url = "http://dev.virtualearth.net/REST/v1/Imagery/Metadata/" +
            this.type + "?" + OpenLayers.Util.getParameterString(params);
        var script = document.createElement("script");
        script.type = "text/javascript";
		//url="http://127.0.0.1:8000/openDemo/demo/openalyer/Layer/go.js";
		//url="http://localhost:8989/SpaceService/MapAction/getMaplib.nut";
        script.src = url;
		//console.log(url);
        script.id = this._callbackId;
        document.getElementsByTagName("head")[0].appendChild(script);
    },
    
    /**
     * Method: initLayer
     *
     * Sets layer properties according to the metadata provided by the API
     */
    initLayer: function() {
        var res = this.metadata.resourceSets[0].resources[0];
        /*
        var url = res.imageUrl.replace("{quadkey}", "${quadkey}");
        this.url = [];
        for (var i=0; i<res.imageUrlSubdomains.length; ++i) {
            this.url.push(url.replace("{subdomain}", res.imageUrlSubdomains[i]));
        };
        */
        this.url=this.options.url;
        this.addOptions({
            maxResolution: Math.min(
                this.serverResolutions[res.zoomMin], this.maxResolution
            ),
            zoomOffset: res.zoomMin,
            numZoomLevels: Math.min(
                res.zoomMax + 1 - res.zoomMin, this.numZoomLevels
            )
        }, true);
    },

    /**
     * Method: getURL
     *
     * Paramters:
     * bounds - {<OpenLayers.Bounds>}
     */
	
    getURL: function(bounds) {
        if (!this.url) {
            return OpenLayers.Util.getImagesLocation() + "blank.gif";
        }
        if(this.bounds!=null){
        	var center = bounds.getCenterLonLat();
       		var point = { x: center.lon, y: center.lat };
        	 var boxbounds=this.bounds;
        	 //boxbounds=boxbounds.transform(this.map.displayProjection,this.map.getProjectionObject());
        	 if(point.x<boxbounds.left)return "http://localhost/tiles/white.gif";
        	 if(point.x>boxbounds.right)return "http://localhost/tiles/white.gif";
        	 if(point.y<boxbounds.bottom)return "http://localhost/tiles/white.gif";
        	 if(point.y>boxbounds.top)return "http://localhost/tiles/white.gif";
        }
        var xyz = this.getXYZ(bounds), x = xyz.x, y = xyz.y, z = xyz.z;
        var quadDigits = [];
        for (var i = z; i > 0; --i) {
            var digit = '0';
            var mask = 1 << (i - 1);
            if ((x & mask) != 0) {
                digit++;
            }
            if ((y & mask) != 0) {
                digit++;
                digit++;
            }
            quadDigits.push(digit);
        }
        var quadKey = quadDigits.join("");
        var url = this.selectUrl('' + x + y + z, this.url);
		//onsole.log("http://localhost/tiles/"+z+"/"+x+"/"+y+".png");
		//return "http://localhost/tiles/"+z+"/"+x+"/"+y+".png";
       // return OpenLayers.String.format(url, {'quadkey': quadKey});
       
        url = OpenLayers.String.format(this.url, { 'x': x, 'y': y, 'z': z });
        return url;
    },
    /**
     * Method: updateAttribution
     * Updates the attribution according to the requirements outlined in
     * http://gis.638310.n2.nabble.com/Bing-imagery-td5789168.html
     */
    updateAttribution: function() {
        var metadata = this.metadata;
        if (!metadata || !this.map || !this.map.center) {
            return;
        }
        var res = metadata.resourceSets[0].resources[0];
        var extent = this.map.getExtent().transform(
            this.map.getProjectionObject(),
            new OpenLayers.Projection("EPSG:4326")
        );
        var providers = res.imageryProviders, zoom = this.map.getZoom() + 1,
            copyrights = "", provider, i, ii, j, jj, bbox, coverage;
        for (i=0,ii=providers.length; i<ii; ++i) {
            provider = providers[i];
            for (j=0,jj=provider.coverageAreas.length; j<jj; ++j) {
                coverage = provider.coverageAreas[j];
                bbox = OpenLayers.Bounds.fromArray(coverage.bbox);
                if (extent.intersectsBounds(bbox) &&
                        zoom <= coverage.zoomMax && zoom >= coverage.zoomMin) {
                    copyrights += provider.attribution + " ";
                }
            }
        }
        this.map && this.map.events.triggerEvent("changelayer", {
            layer: this,
            property: "attribution"
        });
    },
    
    /**
     * Method: setMap
     */
    setMap: function() {
        OpenLayers.Layer.XYZ.prototype.setMap.apply(this, arguments);
        this.updateAttribution();
        this.map.events.register("moveend", this, this.updateAttribution);
    },
    
    /**
     * APIMethod: clone
     * 
     * Parameters:
     * obj - {Object}
     * 
     * Returns:
     * {<OpenLayers.Layer.Bing>} An exact clone of this <OpenLayers.Layer.Bing>
     */
    clone: function(obj) {
        if (obj == null) {
            obj = new OpenLayers.Layer.Bing(this.options);
        }
        //get all additions from superclasses
        obj = OpenLayers.Layer.XYZ.prototype.clone.apply(this, [obj]);
        // copy/set any non-init, non-simple values here
        return obj;
    },
    
    /**
     * Method: destroy
     */
    destroy: function() {
        this.map &&
            this.map.events.unregister("moveend", this, this.updateAttribution);
        OpenLayers.Layer.XYZ.prototype.destroy.apply(this, arguments);
    },
    
    CLASS_NAME: "OpenLayers.Layer.GoogleMap"
});

/**
 * Function: OpenLayers.Layer.Bing.processMetadata
 * This function will be bound to an instance, linked to the global scope with
 * an id, and called by the JSONP script returned by the API.
 *
 * Parameters:
 * metadata - {Object} metadata as returned by the API
 */
OpenLayers.Layer.Bing.processMetadata = function(metadata) {
    this.metadata = metadata;
    this.initLayer();
    var script = document.getElementById(this._callbackId);
    script.parentNode.removeChild(script);
    window[this._callbackId] = undefined; // cannot delete from window in IE
    delete this._callbackId;
};
